/*
*   已通过编译
*   创建互斥量
*   2021.09.27 通过检测
*/
//#include "bsp_adc.h"
//#include "soc/mcpwm_periph.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "driver/mcpwm.h"
#include "bsp_buzz.h"

static const char *TAG = "BSP_BUZZ";
static uint8_t buzz_status;
static SemaphoreHandle_t buzz_mutex;

static void bsp_buzz_gpio_init(void)
{
    mcpwm_gpio_init(CONFIG_HUD_BUZZ_UNIT, CONFIG_HUD_BUZZ_SIGNAL, CONFIG_HUD_BUZZ_GPIO);
}

static void bsp_buzz_set_duty(float duty)
{
    mcpwm_set_duty(CONFIG_HUD_BUZZ_UNIT, CONFIG_HUD_BUZZ_TIMER, MCPWM_OPR_A, duty);
}

void bsp_buzz_init(void)
{
    buzz_mutex = xSemaphoreCreateMutex();
    bsp_buzz_gpio_init();

    ESP_LOGI(TAG, "Configuring Initial Parameters of pwm......");
    mcpwm_config_t pwm_config;
    pwm_config.frequency = CONFIG_HUD_BUZZ_FREQ;
    pwm_config.cmpr_a = 0;
    pwm_config.cmpr_b = 0;
    pwm_config.counter_mode = MCPWM_UP_COUNTER;
    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
    mcpwm_init(CONFIG_HUD_BUZZ_UNIT, CONFIG_HUD_BUZZ_TIMER, &pwm_config); //Configure PWM0A & PWM0B with above settings
    mcpwm_start(CONFIG_HUD_BUZZ_UNIT, CONFIG_HUD_BUZZ_TIMER);
    bsp_buzz_stop();
}

/**反初始化**/
void bsp_buzz_deinit(void)
{
    bsp_buzz_stop();
    vSemaphoreDelete(buzz_mutex);
    //gpio 反初始化
    //pwm 反初始化
}

void bsp_buzz_start(void)
{
    //开启蜂鸣器
    ESP_LOGI(TAG, "Turn on the buzzer");
    buzz_status = 1;
    bsp_buzz_set_duty((float)CONFIG_HUD_BUZZ_DUTY);
}

void bsp_buzz_stop(void)
{
    //关闭蜂鸣器
    ESP_LOGI(TAG, "Turn off the buzzer");
    buzz_status = 0;
    bsp_buzz_set_duty(0);
}

static void bsp_alarm_task(void *arg)
{
    //设置线程锁
    if (xSemaphoreTake(buzz_mutex, portMAX_DELAY) != pdTRUE)
    {
        ESP_LOGI(TAG, "this function is locked!");
        return;
    }

    bsp_buzz_stop();

    uint8_t count = CONFIG_HUD_BUZZ_COUNT;

    while (count > 0)
    {
        if (buzz_status)
        {
            count--;
            bsp_buzz_stop();
        }
        else
        {
            bsp_buzz_start();
        }
        vTaskDelay(CONFIG_HUD_BUZZ_INTERVAL / portTICK_PERIOD_MS);
    }

    ESP_LOGI(TAG, "Stop alarm task");
    xSemaphoreGive(buzz_mutex);
    vTaskDelete(NULL);
}

void bsp_alarm_once(void)
{
    ESP_LOGI(TAG, "Start alarm task");
    xTaskCreate(&bsp_alarm_task, "bsp_alarm_task", 2048, NULL, 5, NULL);
}
